package com.accounting.client;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.accounting.client.remote.Services;
import com.accounting.client.remote.obj.Setting;
import com.accounting.client.remote.obj.SettingKey;
import com.accounting.client.remote.obj.User;
import com.accounting.client.remote.transfer.SearchCurrencyRequest;
import com.accounting.client.remote.transfer.SearchCurrencyResult;
import com.accounting.client.session.ErrorHandler;
import com.accounting.client.session.SessionManager;
import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.user.client.rpc.AsyncCallback;
import corelib.client.CollectionUtil;
import corelib.client.Util;
import corelib.client.date.DateFormats;
import corelib.client.delegate.CompleteCallback;

public class ApplicationContext {
	
	public static double CurrencyRate = 0;
	
	private final static Map<String, User> UserIndex = new HashMap<String, User>();
	private final static Map<String, Setting> SettingIndex = new HashMap<String, Setting>();
	
	public static User getUser(String userId){
		return UserIndex.get(userId);
	}
	
	public static Setting getSetting(String name){
		return SettingIndex.get(name);
	}
	
	public static double getCalculateRate(){
		Setting setting = getSetting(SettingKey.Rate.getName());
		return Util.getDouble(setting.getValue(), 6.0);
	}
	
	public static double getCurrentRate() {
		return CurrencyRate;
	}
	
	public static List<User> getAllUsers(){
		List<User> users = CollectionUtil.newArrayList();
		for (Entry<String, User> user : UserIndex.entrySet()) {
			 if (user != null) {
				 users.add(user.getValue());
			 }
		}
		return users;
	}
	
	public static void Init(final CompleteCallback callback){
		final String passport = SessionManager.getPassport();
		Services.UserService.ListUsers(passport, new AsyncCallback<List<User>>(){
			@Override
			public void onFailure(Throwable caught) {
				ErrorHandler.handleServiceError(caught);
			}
			
			@Override
			public void onSuccess(List<User> result) {
				refreshSettings(callback);
				for (User userInfo : result) {
					 UserIndex.put(userInfo.getUserId(), userInfo);
				}
			}
		});
	}
	
	public static void refreshUsers(final CompleteCallback callback){
		Services.UserService.ListUsers(SessionManager.getPassport(), new AsyncCallback<List<User>>(){
			@Override
			public void onFailure(Throwable caught) {
				ErrorHandler.handleServiceError(caught);
			}
			
			@Override
			public void onSuccess(List<User> result) {
				for (User userInfo : result) {
					 UserIndex.put(userInfo.getUserId(), userInfo);
				}
			}
		});
	}
	
	public static void refreshSettings(final CompleteCallback callback){
		Services.SettingService.GetSettings(SessionManager.getPassport(), new AsyncCallback<List<Setting>>(){
			@Override
			public void onFailure(Throwable caught) {
				ErrorHandler.handleServiceError(caught);
			}
			
			@Override
			public void onSuccess(List<Setting> result) {
				SettingIndex.clear();
				for (Setting setting : result) {
					 SettingIndex.put(setting.getName(), setting);
				}
				refreshCurrentRate(callback);
			}
		});
	}
	
	private static void refreshCurrentRate(final CompleteCallback callback){
		SearchCurrencyRequest request = new SearchCurrencyRequest();
		request.setFrom("AUD");
		request.setTo("CNY");
		Services.CalculateService.GetExchangeRate(SessionManager.getPassport(), request,
			new AsyncCallback<SearchCurrencyResult>(){
				@Override
				public void onFailure(Throwable caught) {
					ErrorHandler.handleServiceError(caught);
				}

				@Override
				public void onSuccess(SearchCurrencyResult result) {
					Log.info(DateFormats.DateTime3.format(result.getDate()) + "-" + result.getRate());
					CurrencyRate = result.getRate();
					callback.onCompleted();
				}
			}
		);
	}
	
}
